home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / edit / mg2a_src.zip / SYS / OSK / FILEIO.C next >
C/C++ Source or Header  |  1988-08-23  |  10KB  |  458 lines

  1. /*
  2.  * Os9/68k fileio.c for MicroGnuEmacs by Robert A. Larson
  3.  *     system dependent file io routines
  4.  */
  5. #include "def.h"
  6. #include "kbd.h"
  7. #include <modes.h>
  8. #include <dir.h>
  9. #include <direct.h>
  10.  
  11. char    *getenv(), *index();
  12.  
  13. static    FILE    *ffp;
  14.  
  15. /*
  16.  * Open a file for reading.
  17.  */
  18. ffropen(fn)
  19. char    *fn;
  20. {
  21.     if ((ffp=fopen(fn, "r")) == NULL) return FIOFNF;
  22.     return FIOSUC;
  23. }
  24.  
  25. /*
  26.  * Open a file for writing.
  27.  */
  28. ffwopen(fn)
  29. char    *fn;
  30. {
  31.     if ((ffp=fopen(fn, "w")) == NULL) {
  32.         ewprintf("Cannot open file %s for writing", fn);
  33.         return FIOERR;
  34.     }
  35.     return FIOSUC;
  36. }
  37.  
  38. /*
  39.  * Close a file.
  40.  * Should look at the status.
  41.  */
  42. ffclose()
  43. {
  44.     fclose(ffp);
  45.     return FIOSUC;
  46. }
  47.  
  48. /*
  49.  * Write a buffer to the already
  50.  * opened file. bp points to the
  51.  * buffer. Return the status.
  52.  * Check only at the newline and
  53.  * end of buffer.
  54.  */
  55. ffputbuf(bp)
  56. BUFFER *bp;
  57. {
  58.     register char *cp;
  59.     register char *cpend;
  60.     register LINE *lp;
  61.     register LINE *lpend;
  62.  
  63.     lpend = bp->b_linep;
  64.     lp = lforw(lpend);
  65.     do {
  66.     cp = <ext(lp)[0];        /* begining of line    */
  67.     cpend = &cp[llength(lp)];    /* end of line        */
  68.     while(cp != cpend) {
  69.         putc(*cp, ffp);
  70.         cp++;    /* putc may evalualte arguments more than once */
  71.     }
  72.     lp = lforw(lp);
  73.     if(lp == lpend) break;        /* no implied newline on last line */
  74.     putc('\n', ffp);
  75.     } while(!ferror(ffp));
  76.     if(ferror(ffp)) {
  77.     ewprintf("Write I/O error");
  78.     return FIOERR;
  79.     }
  80.     return FIOSUC;
  81. }
  82.  
  83. /*
  84.  * Read a line from a file, and store the bytes
  85.  * in the supplied buffer. Stop on end of file or end of
  86.  * line.  When FIOEOF is returned, there is a valid line
  87.  * of data without the normally implied \n.
  88.  */
  89. ffgetline(buf, nbuf, nbytes)
  90. register char    *buf;
  91. register int    nbuf;
  92. register int    *nbytes;
  93. {
  94.     register int    c;
  95.     register int    i;
  96.  
  97.     i = 0;
  98.     while((c = getc(ffp))!=EOF && c!='\n') {
  99.         buf[i++] = c;
  100.         if (i >= nbuf) return FIOLONG;
  101.     }
  102.     if (c == EOF  && ferror(ffp) != FALSE) {
  103.         ewprintf("File read error");
  104.         return FIOERR;
  105.     }
  106.     *nbytes = i;
  107.     return c==EOF ? FIOEOF : FIOSUC;
  108. }
  109.  
  110. #ifndef NO_BACKUP
  111. /*
  112.  * Rename the file "fname" into a backup copy.
  113.  * The backup copy is the same name with ".BAK" appended unless the file
  114.  * name is to long.  The error handling is all in "file.c".
  115.  */
  116. fbackupfile(fname)
  117. char    *fname;
  118. {
  119.     char *rindex();
  120.     register char *backname, *cp;
  121.     int stat;
  122.  
  123.     if((backname = malloc(strlen(fname) + 5)) == NULL) return FALSE;
  124. /* delete the old backup */
  125.     strcpy(backname, fname);
  126.     strcat(backname, ".BAK");
  127.     unlink(backname);            /* ignore errors */
  128.     if(cp = rindex(fname, '/')) {
  129.         strcpy(backname, cp+1);
  130.         strcat(backname, ".BAK");
  131.     }
  132.     stat = rename(fname, backname) >= 0;
  133.     free(backname);
  134.     return stat;
  135. }
  136. #endif
  137.  
  138. #ifdef NO_BACKUP
  139. #ifdef NO_DIRED
  140. #define NO_RENAME
  141. #endif
  142. #endif
  143.  
  144. #ifndef NO_RENAME
  145. rename(frname, toname)
  146. char *frname, *toname;
  147. {
  148.     register char *params;
  149.     register int frnamel, tonamel;
  150.     int status;
  151.  
  152.     frnamel = strlen(frname);
  153.     tonamel = strlen(toname);
  154.     if((params = malloc(frnamel + tonamel + 2)) == NULL) return FALSE;
  155.     strcpy(params, frname);
  156.     params[frnamel] = ' ';
  157.     strcpy(params + frnamel + 1, toname);
  158.     if(os9fork("rename", frnamel + tonamel + 2, params, 0, 0, 0, 0)==-1) {
  159.         free(params);
  160.         return -1;
  161.     }
  162.     wait(&status);
  163.     free(params);
  164.     return (status & 0xffff)==0 ? 0 : -1;
  165. }
  166. #endif
  167.  
  168. /*
  169.  * The string "fn" is a file name.
  170.  * Perform any required appending of directory name or case adjustments.
  171.  * If NO_DIR is not defined, the same file should be refered to even if the
  172.  * working directory changes.  For Os9/68k, leave the file name case alone
  173.  * so we use what the user specified.  (Should, but doesn't, use the case
  174.  * stored on the disk for existing files.)
  175.  */
  176. #ifndef NO_DIR
  177. extern char *wdir;
  178. #endif
  179.  
  180. char *adjustname(fn)
  181. register char    *fn;
  182. {
  183.     static char fnb[NFILEN];
  184.     register char *cp;
  185.     register char *rootp;
  186.  
  187.     switch(*fn) {
  188.         case '/':
  189.         cp = fnb;
  190.         *cp++ = *fn++;
  191.         while(*fn && (*cp++ = *fn++) != '/') {}
  192.         rootp = cp - 1;
  193.         break;
  194.     case '~':
  195.         if(fn[1] != '/') return fn;        /* invalid, punt */
  196.         strcpy(fnb, getenv("HOME"));
  197.         rootp = index(fnb+1, '/');
  198.         cp = fnb + strlen(fnb);
  199.         if(cp==fnb) return fn;        /* invalid */
  200.         if(rootp == NULL) rootp = cp;
  201.         *cp++ = '/';
  202.         fn += 2;
  203.         break;
  204.     default:
  205. #ifndef    NODIR
  206.         strcpy(fnb, wdir);
  207.         rootp = index(fnb+1, '/');
  208.         cp = fnb + strlen(fnb);
  209.         if(cp==fnb) return fn;        /* invalid */
  210.         if(rootp == NULL) rootp = cp;
  211.         *cp++ = '/';
  212.         break;
  213. #else
  214.         return fn;                /* punt */
  215. #endif
  216.     }
  217.     while(*fn) {
  218.         if(*fn == '.') {
  219.         switch(fn[1]) {
  220.             case '\0':
  221.             *--cp = '\0';
  222.             return fnb;
  223.             case '/':
  224.                 fn += 2;
  225.             continue;
  226.         case '.':
  227.             if(fn[2]=='/' || fn[2] == '\0') {
  228.             --cp;
  229.             while(cp > rootp && *--cp != '/') {}
  230.             ++cp;
  231.             if(fn[2]=='\0') {
  232.                 *--cp = '\0';
  233.                 return fnb;
  234.             }
  235.                 fn += 3;
  236.                 continue;
  237.             }
  238.             break;
  239.         default: break;
  240.         }
  241.     }
  242.     while(*fn && (*cp++ = *fn++) != '/') {}
  243.     }
  244.     *cp = '\0';
  245.     return fnb;
  246. }
  247.  
  248. /*
  249.  * fncmp: compare file or buffer names.  Return 0 on equality.  
  250.  * (for compatibility with strcmp)  Both arguments have been 
  251.  * through adjustname.
  252.  */
  253.  
  254. fncmp(fna, fnb)
  255. register char *fna, *fnb;
  256. {
  257.     register char ca, cb;
  258.  
  259.     while(ca = *fna++)
  260.     if(ca != (cb = *fnb++) &&
  261.         (!ISUPPER(ca) || TOLOWER(ca) != cb) &&
  262.         (!ISUPPER(cb) || ca != TOLOWER(cb)))
  263.         return -1;
  264.     return *fnb;
  265. }
  266.  
  267. #ifndef NO_STARTUP
  268. char *startupfile(suffix)
  269. char *suffix;
  270. {
  271.     register char    *file;
  272.     static char    home[NFILEN];
  273.     char        *getenv();
  274.  
  275.     if ((file = getenv("HOME")) == NULL) goto notfound;
  276.     if (strlen(file)+4 >= NFILEN - 1) goto notfound;
  277.     (VOID) strcpy(home, file);
  278.     (VOID) strcat(home, "/.mg");
  279.     if (suffix != NULL) {
  280.         (VOID) strcat(home, "-");
  281.         (VOID) strcat(home, suffix);
  282.     }
  283.     if (access(home, 0) == 0) return home;
  284.  
  285. notfound:
  286. #ifdef    STARTUPFILE
  287.     file = STARTUPFILE;
  288.     if (suffix != NULL) {
  289.         (VOID) strcpy(home, file);
  290.         (VOID) strcat(home, "-");
  291.         (VOID) strcat(home, suffix);
  292.         file = home;
  293.     }
  294.     if (access(file, 0) == 0) return file;
  295. #endif
  296.  
  297.     return NULL;
  298. }
  299. #endif
  300.  
  301. #ifndef NO_DIR
  302. char *getwd(cwd)
  303. char *cwd;
  304. {
  305.     char backpath[MAXPATH];
  306.     char *bpp = backpath, *path = cwd;
  307.     DIR *dirp;
  308.     struct direct *dp;
  309.     long inode, inode2;
  310.     char dots[MAXPATH];
  311.  
  312.     if((dirp = opendir(".")) == NULL || readdir(dirp) == NULL ||
  313.         (dp = readdir(dirp)) == NULL) {
  314.     closedir(dirp);
  315.     return (char *)NULL;
  316.     }
  317.     inode = dp->d_addr;
  318.     *path++ = '/';
  319.     _gs_devn(dirp->dd_fd, path);
  320.     path += strlen(path);
  321.     closedir(dirp);
  322.     strcpy(dots, "..");
  323.     for(;;) {
  324.     if((dirp = opendir(dots)) == NULL || readdir(dirp) == NULL ||
  325.             (dp = readdir(dirp)) == NULL) {
  326.         closedir(dirp);
  327.         return (char *)NULL;
  328.     }
  329.     inode2 = dp->d_addr;
  330.     if(inode == inode2) break;
  331.     do {
  332.         if((dp = readdir(dirp)) == NULL) {
  333.         closedir(dirp);
  334.         return (char *)NULL;
  335.         }
  336.     } while(dp->d_addr != inode);
  337.     *bpp++ = '/';
  338.     strcpy(bpp, dp->d_name);
  339.     bpp += strlen(bpp);
  340.     closedir(dirp);
  341.     inode = inode2;
  342.     strcat(dots, "/..");
  343.     }
  344.     while(bpp > backpath) {
  345.     *bpp = '\0';
  346.     while(*--bpp != '/') {}
  347.     strcpy(path, bpp);
  348.     path += strlen(path);
  349.     }
  350.     return cwd;
  351. }
  352. #endif
  353.  
  354. #ifndef NO_DIRED
  355. copy(frname, toname)
  356. char *frname, *toname;
  357. {
  358.     register char *params;
  359.     register int frnamel, tonamel;
  360.     int status;
  361.  
  362.     frnamel = strlen(frname);
  363.     tonamel = strlen(toname);
  364.     if((params = malloc(frnamel + tonamel + 2)) == NULL) return FALSE;
  365.     strcpy(params, frname);
  366.     params[frnamel] = ' ';
  367.     strcpy(params + frnamel + 1, toname);
  368.     if(os9fork("copy", frnamel + tonamel + 2, params, 0, 0, 0, 0)==-1) {
  369.         free(params);
  370.         return -1;
  371.     }
  372.     wait(&status);
  373.     free(params);
  374.     return (status & 0xffff)==0 ? 0 : -1;
  375. }
  376.  
  377. unlinkdir(fname)
  378. char *fname;
  379. {
  380.     /* does NOT delete non-empty directories */
  381.     if(_ss_attr(fname, S_IWRITE | S_IREAD) < 0) ret